import os
import sys
import time
import argparse
from pathlib import Path
from tqdm import tqdm
import logging

# 导入docx2pdf库
try:
    from docx2pdf import convert
    DOCX2PDF_AVAILABLE = True
except ImportError:
    DOCX2PDF_AVAILABLE = False

# 配置日志（仅控制台输出）
logging.basicConfig(
    level=logging.INFO,
    format='%(message)s',
    handlers=[
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def find_docx_files(directory, recursive=False):
    """查找指定目录下的所有.docx文件"""
    path = Path(directory)
    if recursive:
        return list(path.rglob('*.docx'))
    else:
        return list(path.glob('*.docx'))

def check_file_permissions(file_path):
    """检查文件权限"""
    try:
        # 检查文件是否存在
        if not os.path.exists(file_path):
            return False, "文件不存在"
        
        # 检查读取权限
        if not os.access(file_path, os.R_OK):
            return False, "没有读取权限"
        
        return True, "权限检查通过"
    except Exception as e:
        return False, f"权限检查失败: {str(e)}"

def check_output_dir_permissions(output_dir):
    """检查输出目录权限"""
    try:
        # 确保目录存在
        os.makedirs(output_dir, exist_ok=True)
        
        # 检查写入权限
        if not os.access(output_dir, os.W_OK):
            return False, "输出目录没有写入权限"
        
        # 尝试创建测试文件
        test_file = os.path.join(output_dir, 'test_write_permission.tmp')
        try:
            with open(test_file, 'w') as f:
                f.write('test')
            os.remove(test_file)
        except Exception:
            return False, "无法在输出目录创建文件"
        
        return True, "输出目录权限检查通过"
    except Exception as e:
        return False, f"输出目录权限检查失败: {str(e)}"

def convert_with_docx2pdf(input_file, output_file):
    """使用docx2pdf库进行转换"""
    try:
        if not DOCX2PDF_AVAILABLE:
            return False, "docx2pdf库未安装，请运行: pip install docx2pdf"
        
        # 使用docx2pdf进行转换
        convert(str(input_file), str(output_file))
        
        # 检查输出文件是否创建成功
        if os.path.exists(output_file) and os.path.getsize(output_file) > 0:
            return True, "转换成功"
        else:
            return False, "转换后文件未生成或文件为空"
            
    except Exception as e:
        return False, f"docx2pdf转换失败: {str(e)}"



def convert_docx_to_pdf(input_dir=None, output_dir=None, recursive=False, skip_existing=True):
    """批量转换Word文档为PDF（使用docx2pdf库）
    
    Args:
        input_dir: 输入目录，默认为当前目录
        output_dir: 输出目录，默认与输入目录相同
        recursive: 是否递归搜索子目录
        skip_existing: 是否跳过已存在的PDF文件
    """
    # 检查docx2pdf库是否可用
    if not DOCX2PDF_AVAILABLE:
        logger.error("docx2pdf库未安装，请运行: pip install docx2pdf")
        print("错误: docx2pdf库未安装，请运行: pip install docx2pdf")
        return
    
    # 设置默认目录
    if input_dir is None:
        input_dir = os.getcwd()
    if output_dir is None:
        output_dir = input_dir
    
    # 检查输出目录权限
    perm_ok, perm_msg = check_output_dir_permissions(output_dir)
    if not perm_ok:
        print(f"错误: {perm_msg}")
        return
    
    # 确保输出目录存在
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # 查找所有docx文件
    docx_files = find_docx_files(input_dir, recursive)
    
    if not docx_files:
        print(f"在目录 '{input_dir}' 中未找到.docx文件")
        return
    
    print(f"找到 {len(docx_files)} 个.docx文件，开始转换...")
    
    # 初始化计数器
    success_count = 0
    skipped_count = 0
    failed_count = 0
    
    try:
        
        # 存储已完成的文件列表
        completed_files = []
        
        # 使用进度条显示转换进度
        with tqdm(total=len(docx_files), desc="转换进度", unit="文件",
                  bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}] {postfix}',
                  ncols=100, leave=False) as pbar:
            
            for docx_file in docx_files:
                try:
                    # 检查输入文件权限
                    file_perm_ok, file_perm_msg = check_file_permissions(docx_file)
                    if not file_perm_ok:
                        pbar.set_postfix_str(f"权限错误: {docx_file.name}")
                        failed_count += 1
                        pbar.update(1)
                        continue
                    
                    # 构建输出文件路径
                    if recursive and input_dir != output_dir:
                        # 保持相对路径结构
                        relative_path = docx_file.relative_to(Path(input_dir))
                        output_file = Path(output_dir) / relative_path.with_suffix('.pdf')
                        output_file.parent.mkdir(parents=True, exist_ok=True)
                    else:
                        output_file = Path(output_dir) / (docx_file.stem + '.pdf')
                    
                    # 检查是否跳过已存在的文件
                    if skip_existing and output_file.exists():
                        pbar.set_postfix_str(f"跳过: {docx_file.name}")
                        skipped_count += 1
                        pbar.update(1)
                        continue
                    
                    pbar.set_postfix_str(f"转换: {docx_file.name}")
                    
                    # 使用docx2pdf进行转换
                    success, error_msg = convert_with_docx2pdf(docx_file, output_file)
                    
                    if success:
                        success_count += 1
                        completed_files.append(f"✓ {docx_file.name} -> {output_file.name}")
                        pbar.set_postfix_str(f"完成: {docx_file.name}")
                    else:
                        failed_count += 1
                        pbar.set_postfix_str(f"失败: {docx_file.name}")
                
                except Exception as e:
                    failed_count += 1
                    pbar.set_postfix_str(f"异常: {docx_file.name}")
                
                finally:
                    pbar.update(1)
        
        # 进度条完成后，显示所有已完成的文件
        if completed_files:
            print("\n已完成的转换:")
            for completed in completed_files:
                print(f"  {completed}")
                    
    except Exception as e:
        print(f"转换过程中发生严重错误: {str(e)}")
        return
    
    # 显示转换结果统计
    print(f"\n转换完成!")
    print(f"成功转换: {success_count} 个文件")
    if skipped_count > 0:
        print(f"跳过已存在: {skipped_count} 个文件")
    if failed_count > 0:
        print(f"转换失败: {failed_count} 个文件")

def main():
    """主函数，处理命令行参数"""
    parser = argparse.ArgumentParser(
        description='批量转换Word文档(.docx)为PDF格式',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
示例用法:
  python WordtoPDF.py                    # 转换当前目录下的所有.docx文件
  python WordtoPDF.py -r                 # 递归转换当前目录及子目录下的所有.docx文件
  python WordtoPDF.py -i input_folder    # 转换指定输入目录下的.docx文件
  python WordtoPDF.py -i input -o output # 转换input目录下的文件到output目录
  python WordtoPDF.py -r -f              # 递归转换并强制覆盖已存在的PDF文件
        '''
    )
    
    parser.add_argument('-i', '--input', 
                       help='输入目录路径（默认为当前目录）',
                       default=None)
    
    parser.add_argument('-o', '--output',
                       help='输出目录路径（默认与输入目录相同）',
                       default=None)
    
    parser.add_argument('-r', '--recursive',
                       action='store_true',
                       help='递归搜索子目录中的.docx文件')
    
    parser.add_argument('-f', '--force',
                       action='store_true',
                       help='强制覆盖已存在的PDF文件')
    
    parser.add_argument('--version',
                       action='version',
                       version='WordtoPDF 3.0 - 基于docx2pdf库的批量Word转PDF工具')
    
    args = parser.parse_args()
    
    # 检查输入目录是否存在
    if args.input and not os.path.exists(args.input):
        print(f"错误: 输入目录 '{args.input}' 不存在")
        sys.exit(1)
    
    # 显示配置信息
    input_dir = args.input or os.getcwd()
    output_dir = args.output or input_dir
    
    print("=" * 50)
    print("Word转PDF批量转换工具 v3.0")
    print("=" * 50)
    print(f"输入目录: {input_dir}")
    print(f"输出目录: {output_dir}")
    print(f"递归搜索: {'是' if args.recursive else '否'}")
    print(f"覆盖已存在文件: {'是' if args.force else '否'}")
    print("-" * 50)
    
    try:
        convert_docx_to_pdf(
            input_dir=args.input,
            output_dir=args.output,
            recursive=args.recursive,
            skip_existing=not args.force
        )
    except KeyboardInterrupt:
        print("\n用户中断转换过程")
        sys.exit(1)
    except Exception as e:
        print(f"程序执行出错: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    main()

